package com.xcdh.learn.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.*;
import com.xcdh.domain.vo.R;
import com.xcdh.learn.config.oss.OSSClientConfig;
import com.xcdh.learn.enums.DateFormat;
import com.xcdh.learn.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLDecoder;
import java.util.List;

@Service
@Slf4j
public class OssService {
    // 允许上传的格式
    private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg",
            ".jpeg", ".gif", ".png"};

    @Autowired
    private OSS ossClient ;
    @Autowired
    private OSSClientConfig ossClientConfig ;

    public R uploadImage(MultipartFile uploadFile){

        String fileName = uploadFile.getOriginalFilename();
        if(!checkImg(fileName)){
            log.info("文件格式错误::{}",fileName);
            return R.error("文件格式错误");
        }
        String filePath = getFilePath(fileName);
        try {
            ossClient.putObject(ossClientConfig.getBucketName(), filePath, new
                    ByteArrayInputStream(uploadFile.getBytes()));
            return R.ok(ossClientConfig.getUrlPrefix() + filePath ,"上传成功");
        } catch (IOException e) {
            e.printStackTrace();
            return R.error(e.getMessage())  ;
        }

    }


    /**
     *
     * @desc 生成路径以及文件名 例如：//images/2019/08/10/15564277465972939.jpg
     */
    private String getFilePath(String sourceFileName) {
        return "images/" + DateUtil.format(DateFormat.YEAR)
                + "/" + DateUtil.format(DateFormat.MONTH) + "/"
                + DateUtil.format(DateFormat.DAY) + "/" + System.currentTimeMillis() +
                RandomUtils.nextInt(100, 9999) + "." +
                StringUtils.substringAfterLast(sourceFileName, ".");
    }

    private boolean checkImg(String fileName){
        for (String type : IMAGE_TYPE) {
            if (StringUtils.endsWithIgnoreCase(fileName,type)) {
                return true ;
            }
        }
        return false ;
    }

    /**
     * @desc 下载文件
     */
    public void exportOssFile(OutputStream os, String objectName) throws IOException {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = ossClient.getObject(ossClientConfig.getBucketName(), objectName);
        // 读取文件内容。
        BufferedInputStream in = null ;
        BufferedOutputStream out = null ;
        byte[] buffer = new byte[1024];
        int lenght = 0;
        try{
            in = new BufferedInputStream(ossObject.getObjectContent());
            out = new BufferedOutputStream(os);
            while ((lenght = in.read(buffer)) != -1) {
                out.write(buffer, 0, lenght);
            }
        }finally {
            if (out != null) {
                out.flush(); out.close();
            }
            if (in != null) {
                in.close();
            }
        }
    }


    /**
     * @desc 删除文件
     */
    public R delete(String objectName) {
        // 根据BucketName,objectName删除文件
        ossClient.deleteObject(ossClientConfig.getBucketName(), objectName);
        return R.ok("删除成功");
    }

    /**
     * @desc 查看文件列表
     */
    public R list() {
        // 设置最大个数。
        final int maxKeys = 200;
        // 列举文件。
        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(ossClientConfig.getBucketName()).withMaxKeys(maxKeys));
        List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
        return R.ok(sums ,""  );
    }


    public R batchDelete(List<String> keys){
        DeleteObjectsResult deleteObjectsResult =
                ossClient.deleteObjects(new DeleteObjectsRequest(ossClientConfig.getBucketName()).withKeys(keys));
        List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        try {
            for(String obj : deletedObjects) {
                String deleteObj =  URLDecoder.decode(obj, "UTF-8");
                System.out.println(deleteObj);
            }
            return R.ok("删除文件成功");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return R.ok(e.getMessage());
        }
    }
}
